<!--
 * @Author: Bobby
 * @Date: 2021-12-30 10:01:42
 * @LastEditTime: 2023-09-06 14:52:45
 * @LastEditors: 甯左龙 1173405584@qq.com
 * @Description:
 * @FilePath: \wms-v2\src\ve\elements\basic\uiDynamicTable\uiDynamicTable.vue
 * CIMC-V2
-->
<template>
  <div :id="'uiDynamicTable-body-' + info._id" ref="uiDynamicTable-body" class="ui-dynamic-tabel relative" :class="[hasMini ? 'table-mini' : '']">
    <div class="min-h-[20px]"></div>
    <vxe-grid
      :ref="info._id"
      v-ui-ref="vSetRef"
      v-bind="gridOptions"
      :scroll-x="{ gt: 10 }"
      :scroll-y="{ gt: 50 }"
      @cell-dblclick="cellDBLClickEvent"
      @page-change="pageChange"
    >
      <!-- 工具栏 -->
      <template #toolbar_tools>
        <vxe-button class="refresh-btn" size="mini" @click="onRefresh">
          <vui-icon :class="{ roll: hasClickRefreshLoading }" icon="refresh-line" />
        </vxe-button>
      </template>
      <!-- 多选头 -->
      <template #checkbox_header="{ checked, indeterminate }">
        <div class="flex cursor-pointer">
          <span class="custom-checkbox" @click.stop="checkboxSelectAll">
            <template v-if="indeterminate">
              <i class="ri-checkbox-indeterminate-line text-blue-500"></i>
            </template>
            <template v-else-if="checked">
              <i class="ri-checkbox-fill text-blue-500"></i>
            </template>
            <template v-else>
              <i class="ri-checkbox-blank-line text-gray-300"></i>
            </template>
          </span>
          <!-- <span @click="checkboxSelectAll">{{ column.title }}</span> -->
          <span>/</span>
          <span @click="checkboxReverseSelection">{{ translateTitle(`Ve.elements.table.反选`) }}</span>
        </div>
      </template>

      <!-- 空数据 -->
      <template #empty>
        <el-empty :description="translateTitle('Ve.elements.table.暂无数据')" />
      </template>
    </vxe-grid>
  </div>
</template>
<script>
  import { defineComponent } from 'vue'
  import { UiMixin, RefsInjectMixin } from '@ve/mixin'
  import { domHeight } from '@ve/utils/domHeight'
  import request from '@/utils/request'
  import { GFCD } from '@/utils/utils'
  import isEmpty from 'lodash/isEmpty'
  import isArray from 'lodash/isArray'
  import trim from 'lodash/trim'
  import cloneDeep from 'lodash/cloneDeep'
  import isFunction from 'lodash/isFunction'
  import isPlainObject from 'lodash/isPlainObject'
  import { processingConstant, replaseRegVariable } from '@ve/utils/utils'
  import { translateTitle } from '@/utils/i18n'

  export default defineComponent({
    name: 'UiDynamicTable',
    components: {},
    mixins: [UiMixin, RefsInjectMixin],

    data() {
      return {
        tabelHeight: 300,
        tableColumns: [],
        tableDataList: [],
        pageSize: 1,
        hasClickRefreshLoading: false,
        hasMini: false,
        loading: false,
      }
    },
    computed: {
      getExtension() {
        return this.info.extension
      },
      getCount() {
        return this.info.data.requestData.count
      },
      currentPage() {
        return this.info.data.formData['#LIMIT#']
      },
      reviseField() {
        return this.info.extension.reviseField.value
      },
      valueField() {
        return this.info.extension.valueField.value
      },
      fixedField() {
        return this.info.extension.fixedField.value
      },
      RDField() {
        return this.info.extension.RDField.value
      },
      gridOptions() {
        let gridOptionsData = {
          rowConfig: {
            useKey: true,
            isHover: true,
            isCurrent: true,
          },
          columnConfig: {
            useKey: true,
            resizable: true,
          },
          data: this.tableDataList,
          showHeaderOverflow: true,
          keepSource: true,
          columnKey: true,
          stripe: true,
          loading: this.loading,
          resizable: true,
          autoResize: true,
          border: true,
          showOverflow: true,
          height: this.tabelHeight, //'auto',
          radioConfig: { highlight: true },
          checkboxConfig: { highlight: true },
          // pagerConfig: {
          //   size: 'mini',
          //   pageSizes: this.info.extension.pageSizes.value.map((v) => Number(v)),
          //   pageSize: this.pageSize,
          //   total: this.getCount || 0,
          //   currentPage: this.currentPage,
          // },
          columns: this.getTableColumns,
          toolbarConfig: {
            slots: {
              tools: 'toolbar_tools',
            },
            className: 'vui-toolbar-box',
            // custom: {
            //   trigger: 'click',
            // },
            custom: false,
          },
        }
        return gridOptionsData
      },
      getTableColumns() {
        let _tableColumns = [...cloneDeep(this.tableColumns)]

        _tableColumns.forEach((v) => {
          v.width = `${v.width}px`
          v['minWidth'] = '70px'
          if (v._type === 'checkbox') {
            v['width'] = '56px'
            v.slots = {
              header: 'checkbox_header',
            }
          }

          if (v._type === 'seq') {
            v['width'] = '50px'
          }

          v['showHeaderOverflow'] = true
          v['searchConfig'] = v['searchConfig'] || {}
          //是否开启编辑 添加配置文件
          if (v.openEdit && this.hasOpenEdit) {
            v.editRender = {}
            if (v.slots) {
              v.slots['edit'] = v.field
            } else {
              v.slots = {
                edit: v.field,
              }
            }

            // this.editSlots.push(v.field)
            this.editSlots.push({
              field: v.field,
              formItemType: v.formModuleType || {},
            })
          } else {
            if (v.slots) {
              delete v.slots.edit
            }
          }
        })
        console.log('_tableColumns', _tableColumns)
        return _tableColumns
      },
    },
    created() {
      // 计算高度
      this.$sub(`SplitpaneResized_${this.previewPageId()}`, () => {
        this.getHeight()

        setTimeout(() => {
          this.getTableWidthProportion()
          // console.log('表格宽度变化', this.getTableRef().$el, this.getTableRef().$el.clientWidth)
        }, 200)
      })
    },
    mounted() {
      setTimeout(() => {
        this.getHeight()
      }, 500)

      // console.log(this.info)
      // 调用接口
      if (!this.getInfo.extension.notRequest || !this.getInfo.extension.notRequest.value) {
        if (this.getInfo.extension.api.value) this.requestData()
      }

      // 模拟调用接口 转化数据
      // this.handleTableData(this.tableData)
    },
    methods: {
      translateTitle,
      getHeight() {
        // debugger
        let _tabelHeight = domHeight(this)
        if (_tabelHeight > 0) {
          this.tabelHeight = _tabelHeight
        }
      },
      requestData(cb) {
        let requestDataObj = {}
        isArray(this.info.extension.requestData.value) &&
          this.info.extension.requestData.value.forEach((item) => {
            let itemVal = item.value
            if (/#{.*?}/g.test(item.value)) {
              itemVal = replaseRegVariable(itemVal, this.info.data.formData)
            }
            requestDataObj[item.key] = processingConstant(this, itemVal)
          })
        let options = {
          api: this.info.extension.api.value,
          method: this.info.extension.method.value,
          getDataKey: this.info.extension.getDataKey.value,
          data: { ...this.info.data.formData, ...requestDataObj },
        }
        if (!trim(options.api)) return
        this.request(options, cb)
      },
      // 统一请求
      request(options = {}, cb) {
        this.loading = true
        let getDataKey = this.getExtension.getDataKey.value
        //发起请求
        return request({
          url: GFCD('dams', 'domain') + options.api,
          method: 'post',
          data: {
            data: JSON.stringify(options.data),
            method: options.method,
          },
        }).then((res) => {
          this.loading = false
          let requestData = isEmpty(getDataKey) ? res.data : res.data[getDataKey]
          requestData && this.handleTableData(requestData.data)
          // 事件回调
          cb && cb(res)
        })
      },
      // 自定义渲染函数
      formatterColumn({ cellValue }) {
        if (isPlainObject(cellValue)) {
          return cellValue[this.valueField]
        } else {
          return cellValue
        }
      },
      // 表格数据处理函数
      handleTableData(tableData) {
        let _tableColumns = []
        // 先添加静态列
        this.fixedField.split(',').forEach((item) => {
          _tableColumns.push({
            _type: 'field',
            title: trim(item),
            field: trim(item),
          })
        })
        let equipmentList = []
        // 先遍历数据列表 查找要生成的表格头
        tableData.forEach((item) => {
          if (item[this.reviseField]) {
            let equipment = item[this.reviseField]
            // 如果当前项的 反转字段有值 则添加当前字段值至表头
            if (equipmentList.indexOf(equipment) === -1) {
              // 添加临时缓存
              equipmentList.push(equipment)
              // 添加表头
              _tableColumns.push({
                _type: 'field',
                title: equipment,
                field: equipment,
                formatter: this.formatterColumn,
              })
            }
          }
        })

        // 生成表格数据
        let itemList = []
        let _tableData = []
        tableData.forEach((item) => {
          if (itemList.indexOf(item[this.RDField]) === -1) {
            // 先将当前日期记录为已处理
            itemList.push(item[this.RDField])
            // 再遍历数据列表找到当前日期的数据 然后记录有数据的
            let tableDataItem = {}
            // 先添加静态列数据
            this.fixedField.split(',').forEach((fieldItem) => {
              tableDataItem[trim(fieldItem)] = item[trim(fieldItem)]
            })
            // 再添加反转后的动态数据
            tableData.forEach((childItem) => {
              if (childItem[this.RDField] === item[this.RDField]) {
                // tableDataItem[childItem[this.reviseField]] = childItem[this.valueField]
                childItem[this.reviseField] && (tableDataItem[childItem[this.reviseField]] = childItem)
              }
            })
            _tableData.push(tableDataItem)
          }
        })

        console.log()
        this.tableColumns = _tableColumns
        this.tableDataList = _tableData
      },
      onRefresh(callback) {
        this.hasClickRefreshLoading = true
        this.$refreshTable().then(() => {
          if (isFunction(callback)) callback(this)
          this.hasClickRefreshLoading = false
        })
      },
      // 刷新表格
      $refreshTable() {
        this.setFormData(1, this.pageSize)
        //请求
        return this.requestData()
      },
      setFormData(currentPage, pageSize) {
        this.getInfo.data.formData['#LIMIT#'] = currentPage
        this.getInfo.data.formData['#PAGE_SIZE#'] = pageSize
        this.pageSize = pageSize
      },
      getTableRef() {
        return this.$refs[this.getInfo._id]
      },
      getTableWidthProportion() {
        if (this.getTableRef() && this.getTableRef().$el) {
          let _tableWidth = this.getTableRef().$el.clientWidth
          let _winWidth = document.body.clientWidth
          // console.log('表格宽度变化', this.getTableRef().$el, _tableWidth, _winWidth, parseFloat((_tableWidth / _winWidth) * 100))
          let _proportion = parseFloat((_tableWidth / _winWidth) * 100)
          this.hasMini = _proportion <= 30 ? true : false
        }
      },
      // 单元格双击事件
      cellDBLClickEvent(data) {
        console.log('data ========== ', data)
        if (data.column && data.column.title == '操作') {
          console.log('点击操作区域不执行双行事件')
          return
        }
        if (!this.hasPreview) {
          console.log('预览模式不运行 onDbClick')
          return
        }

        const field = data.column.field
        const cellValue = data.row[field]
        if (isPlainObject(cellValue)) {
          // 如果当前点击的单元格数据格式为对象 则代表点击了有效单元格
          this.runEventTask('onTableDblClick', {
            tableId: this.info._id,
            data: cellValue,
          })
        }
      },
      // page修改
      pageChange(e) {
        let { currentPage, pageSize } = e
        if (this.pageSize != pageSize) {
          currentPage = 1
        }
        //页面修改 初始化到1页
        this.setFormData(currentPage, pageSize)
        //请求
        this.requestData()
      },
      // 事件调用请求数据方法
      $requestData(cb) {
        this.requestData(cb)
      },
    },
  })
</script>
<style lang="scss" scoped></style>
